class ResidualBlock(nn.Module):
    def __init__(self, inC, outC, stride=1): 
        #__init()中定义可学习的参数
        super(ResidualBlock, self).__init__()  
         # 左边支路
        # 指残差块中按顺序执行的普通卷积网络
        self.left = nn.Sequential(
            # 注意此处可能步长会改变
            nn.Conv2d(inC,outC, kernel_size=3, stride=stride,padding=1,bias=False),
            nn.BatchNorm2d(outC), 
            #最常用于卷积网络中(防止梯度消失或爆炸)
            nn.ReLU(inplace=True), 
            #implace=True是把输出直接覆盖到输入中,节省内存
            nn.Conv2d(inC,outC,kernel_size=3, stride=1,padding=1, bias=False),   
            nn.BatchNorm2d(outC)
        ) 
        # 右边支路
        self.shortcut = nn.Sequential()
        # 若右边支路进行了尺度降stride倍,
        # 则这边运用卷积层,用同样步长降,再加一个BN层
        if stride != 1 or inC != outC:
            # 只有步长为1并且输入通道和输出通道相等
            # 特征图大小才会一样,如果不一样,需要在合并之前进行统一
            self.shortcut = nn.Sequential(
                nn.Conv2d(inC,outC,kernel_size=1,stride=stride, padding=0,bias=False),
                nn.BatchNorm2d(outchannel)
            )
    def forward(self, x):#实现前向传播过程
        out = self.left(x)#先执行普通卷积神经网络
        out += self.shortcut(x)#再加上原始x数据
        # 最后加一个ReLU激活函数
        out = F.relu(out)
        return out 
